#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys/types.h>
#include <threads.h>
#include <time.h>

#include "h_mempool.h"
#include "h_mulit_mempool.h"

#define NODE_SIZE       100000
#define EXPAND_SIZE     64

typedef struct node_s {
    uint32_t a;
    uint64_t b;
    uint8_t up[1500];
    uint8_t down[1500];


    uint8_t target_host[300];
    uint16_t target_port;

    uint8_t reserve[322];
} node_t;

void test_h_mempool() {
    printf("node_t size: %ld\n", sizeof(node_t));
    h_mempool_t *mempool = h_mempool_new();
    if (mempool == NULL) {
        printf("chunk: %ld\n", sizeof(chunk_t));
        return;
    }
    printf("mempool new\n");
    h_mempool_print(mempool, false);

    if (!h_mempool_init(mempool, NODE_SIZE, EXPAND_SIZE, sizeof(node_t))) {
        printf("mempool init failed\n");
        return;
    }
    printf("mempool init\n");
    h_mempool_print(mempool, false);
    
    node_t *node[6] = {NULL};
    for (int i = 0; i < 6; i++) {
        node[i] = h_mempool_get(mempool);
        if (node[i] == NULL) {
            printf("mempool get failed\n");
        }
        printf("mempool get node: %p\n", node[i]);
    }
    h_mempool_print(mempool, false);

    for (int i = 5; i >= 0; i--) {
        if (node[i] != NULL) {
            printf("mempool put node: %p\n", node[i]);
            h_mempool_put(mempool, node[i]);
        }        
    }
    h_mempool_print(mempool, false);
    h_mempool_clear(mempool);
    printf("mempool clear\n");
    h_mempool_print(mempool, true);
    h_mempool_destroy(mempool);
    printf("mempool destroy\n");
    mempool = NULL;
    h_mempool_print(mempool, true);
}

void test_h_mulit_mempool() {
    printf("node_t size: %ld\n", sizeof(node_t));
    h_mulit_mempool_t *mulit_mempool = h_mulit_mempool_new();
     if (mulit_mempool == NULL) {
        printf("chunk: %ld\n", sizeof(chunk_t));
        return;
    }
    printf("mulit_mempool new\n");
    h_mulit_mempool_print(mulit_mempool, false);

    if (!h_mulit_mempool_init(mulit_mempool, 6, 5, EXPAND_SIZE, 0, 1500)) {
        printf("mulit_mempool init failed\n");
        return;
    }
    printf("mulit_mempool init\n");
    h_mulit_mempool_print(mulit_mempool,false);
    uint8_t *node[6] = {NULL};
    for (int i = 0; i < 6; i++) {
        uint32_t size = 1400 * (i + 1);
        node[i] = h_mulit_mempool_get(mulit_mempool, size);
        if (node[i] == NULL) {
            printf("mulit_mempool get size %u failed\n", size);
        }
        printf("mulit_mempool get size %u node: %p\n", size, node[i]);
    }
    h_mulit_mempool_print(mulit_mempool, false);

    for (int i = 5; i >= 0; i--) {
        if (node[i] != NULL) {
            printf("mulit_mempool put node: %p\n", node[i]);
            h_mulit_mempool_put(mulit_mempool, node[i]);
        }        
    }
    h_mulit_mempool_print(mulit_mempool,false);
    // sleep(10);
    h_mulit_mempool_destroy(mulit_mempool);
    printf("mulit_mempool destroy\n");
    mulit_mempool = NULL;
    h_mulit_mempool_print(mulit_mempool, true);
}

int main() {
    // test_h_mempool();
    test_h_mulit_mempool();
    return 0;
}